home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / raid / devRaidLock.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  8.0 KB  |  376 lines

  1. /* 
  2.  * devRaidLock.c --
  3.  *
  4.  *    Routines for locking and unlocking RAID stripes.
  5.  *    Note that because of the manner in which these routines are used,
  6.  *    stripes with the same number in different arrays (i.e. different
  7.  *    unit numbers) will share the same lock.  Therefore, care must be
  8.  *    taken to avoid unexpected deadlocks (i.e. a single process should never
  9.  *    simultaneously lock two stripes in different raid devices).
  10.  *    All locks are exclusive.
  11.  *
  12.  * Copyright 1989 Regents of the University of California
  13.  * Permission to use, copy, modify, and distribute this
  14.  * software and its documentation for any purpose and without
  15.  * fee is hereby granted, provided that the above copyright
  16.  * notice appear in all copies.  The University of California
  17.  * makes no representations about the suitability of this
  18.  * software for any purpose.  It is provided "as is" without
  19.  * express or implied warranty.
  20.  *
  21.  */
  22.  
  23. #ifndef lint
  24. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/raid/devRaidLock.c,v 1.12 92/06/25 17:21:04 eklee Exp $ SPRITE (Berkeley)";
  25. #endif /* not lint */
  26.  
  27. #include "sync.h"
  28. #include <sprite.h>
  29. #include <stdio.h>
  30. #include "hash.h"
  31. #include "devRaid.h"
  32. #include "semaphore.h"
  33. #include "devRaidProto.h"
  34.  
  35. extern char *malloc();
  36.  
  37. #define LOCK_TABLE_SIZE    4096
  38.  
  39. static Hash_Table lockTable;
  40. static Sync_Semaphore mutex =
  41.     Sync_SemInitStatic("devRaidLock.c: Stripe Lock Table");
  42.  
  43.  
  44. /*
  45.  *----------------------------------------------------------------------
  46.  *
  47.  * Raid_InitStripeLocks --
  48.  *
  49.  *    Should be called at least once before calling any other procedure
  50.  *    from this module.
  51.  *
  52.  * Results:
  53.  *    None.
  54.  *
  55.  * Side effects:
  56.  *    Initializes stripe lock table.
  57.  *
  58.  *----------------------------------------------------------------------
  59.  */
  60.  
  61. void
  62. Raid_InitStripeLocks()
  63. {
  64.     static int    initialized = 0;
  65.  
  66.     MASTER_LOCK(&mutex);
  67.     if (initialized == 0) {
  68.     initialized = 1;
  69.         MASTER_UNLOCK(&mutex);
  70.     Hash_Init(&lockTable, 1000, 1);
  71.     } else {
  72.     MASTER_UNLOCK(&mutex);
  73.     }
  74. }
  75.  
  76.  
  77. /*
  78.  *----------------------------------------------------------------------
  79.  *
  80.  * Raid_SLockStripe --
  81.  *
  82.  * Results:
  83.  *    None.
  84.  *
  85.  * Side effects:
  86.  *    Share lock requested stripe.
  87.  *
  88.  *----------------------------------------------------------------------
  89.  */
  90.  
  91. void
  92. Raid_SLockStripe(raidPtr, stripe)
  93.     Raid *raidPtr;
  94.     int stripe;
  95. {
  96.     Hash_Entry        *hashEntryPtr;
  97.     Sync_Condition    *condPtr;
  98.     condPtr = (Sync_Condition *) Malloc(sizeof(Sync_Condition));
  99.  
  100.     MASTER_LOCK(&mutex);
  101.     hashEntryPtr = Hash_Find(&lockTable, (Address) stripe);
  102.     while ( Hash_GetValue(hashEntryPtr) != (char *) NIL ) {
  103.     Sync_MasterWait((Sync_Condition *) Hash_GetValue(hashEntryPtr),
  104.         &mutex, FALSE);
  105.         hashEntryPtr = Hash_Find(&lockTable, (Address) stripe);
  106.     }
  107. #ifdef TESTING
  108.     Sync_CondInit(condPtr);
  109. #endif TESTING
  110.     Hash_SetValue(hashEntryPtr, condPtr);
  111.     MASTER_UNLOCK(&mutex);
  112. }
  113.  
  114.  
  115. /*
  116.  *----------------------------------------------------------------------
  117.  *
  118.  * Raid_XLockStripe --
  119.  *
  120.  * Results:
  121.  *    None.
  122.  *
  123.  * Side effects:
  124.  *    Exclusively lock requested stripe.
  125.  *
  126.  *----------------------------------------------------------------------
  127.  */
  128. void
  129. Raid_XLockStripe(raidPtr, stripe)
  130.     Raid *raidPtr;
  131.     int stripe;
  132. {
  133.     Raid_SLockStripe(raidPtr, stripe);
  134.     Raid_LogStripe(raidPtr, stripe);
  135. #ifdef TESTING
  136.     CheckStripeLog(raidPtr, stripe); 
  137. #endif /* TESTING */
  138. }
  139.  
  140.  
  141. /*
  142.  *----------------------------------------------------------------------
  143.  *
  144.  * Raid_SUnlockStripe --
  145.  *
  146.  * Results:
  147.  *    None.
  148.  *
  149.  * Side effects:
  150.  *    Unlocks requested stripe.
  151.  *
  152.  *----------------------------------------------------------------------
  153.  */
  154.  
  155. void
  156. Raid_SUnlockStripe(raidPtr, stripe)
  157.     Raid *raidPtr;
  158.     int stripe;
  159. {
  160.     Hash_Entry        *hashEntryPtr;
  161.     Sync_Condition    *condPtr;
  162.  
  163.     MASTER_LOCK(&mutex);
  164.     hashEntryPtr = Hash_Find(&lockTable, (Address) stripe);
  165.     if ( Hash_GetValue(hashEntryPtr) == (char *) NIL ) {
  166.     MASTER_UNLOCK(&mutex);
  167.     panic("Error: UnlockStripe: Attempt to unlock unlocked stripe.");
  168.     }
  169.     condPtr = (Sync_Condition *) Hash_GetValue(hashEntryPtr);
  170.     Sync_MasterBroadcast(condPtr);
  171.     Hash_Delete(&lockTable, hashEntryPtr);
  172.     MASTER_UNLOCK(&mutex);
  173.     Free((char *) condPtr);
  174. }
  175.  
  176.  
  177. /*
  178.  *----------------------------------------------------------------------
  179.  *
  180.  * Raid_XUnlockStripe --
  181.  *
  182.  * Results:
  183.  *    None.
  184.  *
  185.  * Side effects:
  186.  *    Unlocks requested stripe.
  187.  *
  188.  *----------------------------------------------------------------------
  189.  */
  190.  
  191. void
  192. Raid_XUnlockStripe(raidPtr, stripe)
  193.     Raid *raidPtr;
  194.     int stripe;
  195. {
  196. #ifdef TESTING
  197.     CheckStripeLog(raidPtr, stripe); 
  198. #endif /* TESTING */
  199.     Raid_UnlogStripe(raidPtr, stripe);
  200.     Raid_SUnlockStripe(raidPtr, stripe);
  201. }
  202.  
  203. /*
  204.  *----------------------------------------------------------------------
  205.  *
  206.  * Raid_Disable --
  207.  *
  208.  * Results:
  209.  *    Disable non-exclusive access.
  210.  *
  211.  * Side effects:
  212.  *    Gains exclusive access to specified RAID device.
  213.  *
  214.  *----------------------------------------------------------------------
  215.  */
  216. void
  217. Raid_Disable(raidPtr)
  218.     Raid *raidPtr;
  219. {
  220.     MASTER_LOCK(&raidPtr->mutex);
  221.     raidPtr->numWaitExclusive++;
  222.     MASTER_UNLOCK(&raidPtr->mutex);
  223. }
  224.  
  225. /*
  226.  *----------------------------------------------------------------------
  227.  *
  228.  * Raid_Enable --
  229.  *
  230.  * Results:
  231.  *    Locks a disabled RAID.
  232.  *
  233.  * Side effects:
  234.  *    Gains exclusive access to specified RAID device.
  235.  *
  236.  *----------------------------------------------------------------------
  237.  */
  238. void
  239. Raid_Enable(raidPtr)
  240.     Raid *raidPtr;
  241. {
  242.     MASTER_LOCK(&raidPtr->mutex);
  243.     raidPtr->numWaitExclusive--;
  244.     Sync_MasterBroadcast(&raidPtr->waitExclusive);
  245.     Sync_MasterBroadcast(&raidPtr->waitNonExclusive);
  246.     MASTER_UNLOCK(&raidPtr->mutex);
  247. }
  248.  
  249. /*
  250.  *----------------------------------------------------------------------
  251.  *
  252.  * Raid_IsLocked --
  253.  *
  254.  * Results:
  255.  *
  256.  * Side effects:
  257.  *
  258.  *----------------------------------------------------------------------
  259.  */
  260.  
  261. int
  262. Raid_IsLocked(raidPtr)
  263.     Raid *raidPtr;
  264. {
  265.     return raidPtr->numReqInSys == -1;
  266. }
  267.  
  268. /*
  269.  *----------------------------------------------------------------------
  270.  *
  271.  * Raid_Lock --
  272.  *
  273.  * Results:
  274.  *    None.
  275.  *
  276.  * Side effects:
  277.  *    Gains exclusive access to specified RAID device.
  278.  *
  279.  *----------------------------------------------------------------------
  280.  */
  281.  
  282. void
  283. Raid_Lock (raidPtr)
  284.     Raid *raidPtr;
  285. {
  286.     MASTER_LOCK(&raidPtr->mutex);
  287.     raidPtr->numWaitExclusive++;
  288.     while (raidPtr->numReqInSys != 0) {
  289.     Sync_MasterWait(&raidPtr->waitExclusive, &raidPtr->mutex, FALSE);
  290.     }
  291.     raidPtr->numWaitExclusive--;
  292.     raidPtr->numReqInSys = -1;
  293.     MASTER_UNLOCK(&raidPtr->mutex);
  294. }
  295.  
  296.  
  297. /*
  298.  *----------------------------------------------------------------------
  299.  *
  300.  * Raid_Unlock --
  301.  *
  302.  * Results:
  303.  *    None.
  304.  *
  305.  * Side effects:
  306.  *    Releases exclusive access to specified RAID device.
  307.  *
  308.  *----------------------------------------------------------------------
  309.  */
  310.  
  311. void
  312. Raid_Unlock (raidPtr)
  313.     Raid *raidPtr;
  314. {
  315.     MASTER_LOCK(&raidPtr->mutex);
  316.     raidPtr->numReqInSys = 0;
  317.     if (raidPtr->numWaitExclusive > 0) {
  318.     Sync_MasterBroadcast(&raidPtr->waitExclusive);
  319.     } else {
  320.     Sync_MasterBroadcast(&raidPtr->waitNonExclusive);
  321.     }
  322.     MASTER_UNLOCK(&raidPtr->mutex);
  323. }
  324.  
  325.  
  326. /*
  327.  *----------------------------------------------------------------------
  328.  *
  329.  * Raid_BeginUse --
  330.  *
  331.  * Results:
  332.  *    None.
  333.  *
  334.  * Side effects:
  335.  *
  336.  *----------------------------------------------------------------------
  337.  */
  338.  
  339. void
  340. Raid_BeginUse (raidPtr)
  341.     Raid *raidPtr;
  342. {
  343.     MASTER_LOCK(&raidPtr->mutex);
  344.     while (raidPtr->numReqInSys == -1 || raidPtr->numWaitExclusive > 0) {
  345.     Sync_MasterWait(&raidPtr->waitNonExclusive, &raidPtr->mutex, FALSE);
  346.     }
  347.     raidPtr->numReqInSys++;
  348.     MASTER_UNLOCK(&raidPtr->mutex);
  349. }
  350.  
  351.  
  352. /*
  353.  *----------------------------------------------------------------------
  354.  *
  355.  * Raid_EndUse --
  356.  *
  357.  * Results:
  358.  *    None.
  359.  *
  360.  * Side effects:
  361.  *
  362.  *----------------------------------------------------------------------
  363.  */
  364.  
  365. void
  366. Raid_EndUse (raidPtr)
  367.     Raid *raidPtr;
  368. {
  369.     MASTER_LOCK(&raidPtr->mutex);
  370.     raidPtr->numReqInSys--;
  371.     if (raidPtr->numReqInSys == 0) {
  372.     Sync_MasterBroadcast(&raidPtr->waitExclusive);
  373.     }
  374.     MASTER_UNLOCK(&raidPtr->mutex);
  375. }
  376.